// 
// Bachelor of Software Engineering
// Media Design School
// Auckland
// New Zealand
//
// (c) 2005 - 2014 Media Design School
//
// File Name	: Rect.cpp
// Desrciption	: CRect implementation file.
// Author(s)	: Hayden Asplet.
// Mail			: hayden.asplet@mediadesignschool.com
//

// PCH
#include "GameStd.h"

// Library Includes

// This Include
#include "Rect.h"
#include "Point.h"

// Local Includes

CRect::CRect()
	:m_iX(0),
	m_iY(0),
	m_iWidth(0),
	m_iHeight(0)
{

}

CRect::CRect(int _iX, int _iY, int _iW, int _iH)
	:m_iX(_iX),
	m_iY(_iY),
	m_iWidth(_iW),
	m_iHeight(_iH)
{

}

CRect::CRect(const CRect& _krRect)
	:m_iX(_krRect.m_iX),
	m_iY(_krRect.m_iY),
	m_iWidth(_krRect.m_iWidth),
	m_iHeight(_krRect.m_iHeight)
{

}

CRect& CRect::operator=(const CRect& _krRect)
{
	m_iX = _krRect.m_iX;
	m_iY = _krRect.m_iY;
	m_iWidth = _krRect.m_iWidth;
	m_iHeight = _krRect.m_iHeight;

	return *this;
}

bool CRect::operator==(const CRect& _krRect)
{
	return m_iX == _krRect.m_iX && 
		   m_iY == _krRect.m_iY &&
		   m_iWidth == _krRect.m_iWidth &&
		   m_iHeight == _krRect.m_iHeight;
}

bool CRect::operator!=(const CRect& _krRect)
{
	return !(*this == _krRect);
}

bool CRect::IsInBounds(int _iX, int _iY) const // Code added by Juran
{
	if(_iX >= m_iX && _iY >= m_iY &&
	   _iX <= m_iWidth + m_iX && _iY <= m_iHeight + m_iY)
	{
		return true;
	}

	return false;
}

bool CRect::IsInBounds(const CPoint& _krPoint) const // Code added by Juran
{
	if(_krPoint.m_iX >= m_iX && 
	   _krPoint.m_iY >= m_iY &&
	   _krPoint.m_iX <= m_iWidth + m_iX &&
	   _krPoint.m_iY <= m_iHeight + m_iY)
	{
		return true;
	}

	return false;
}

void CRect::SetPosition(int _iX, int _iY) // Code added by Juran
{
	m_iX = _iX;
	m_iY = _iY;
}

void CRect::SetPosition(const CPoint& _krPoint) // Code added by Juran
{
	m_iX = _krPoint.m_iX;
	m_iY = _krPoint.m_iY;
}

CPoint CRect::GetPosition() const
{
	return CPoint(m_iX, m_iY);
}

bool IsIntersecting(const CRect& _krRectA, const CRect& _krRectB)
{
	if(_krRectA.m_iX + _krRectA.m_iWidth < _krRectB.m_iX) {
	// _krRectA is to the left.
		return false;
	}
	else if(_krRectA.m_iY + _krRectA.m_iHeight < _krRectB.m_iY) {
	// _krRectA is above.
		return false;
	}
	else if(_krRectA.m_iX > _krRectB.m_iX + _krRectB.m_iWidth) {
	// _krRectA is to the right.
		return false;
	}
	else if(_krRectA.m_iY > _krRectB.m_iY + _krRectB.m_iHeight) {
	// _krRectA is below.
		return false;
	}
	else {
	// _krRectA and _krRectB are intersecting.
		return true;
	}

	return false;
}

int AreaOfOverlap(const CRect& _krRectA, const CRect& _krRectB)
{
	int iOverlapWidth = 0;
	int iOverlapHeight = 0;

	int iRightA = _krRectA.m_iX + _krRectA.m_iWidth;
	int iRightB = _krRectB.m_iX + _krRectB.m_iWidth;
	int iBottomA = _krRectA.m_iY + _krRectA.m_iHeight;
	int iBottomB = _krRectB.m_iY + _krRectB.m_iHeight;
	
	if(iRightA > iRightB) {
		iOverlapWidth = iRightB - _krRectA.m_iX;
	}
	else {
		iOverlapWidth = iRightA - _krRectB.m_iX;
	}

	if(iBottomA > iBottomB) {
		iOverlapHeight = iBottomB - _krRectA.m_iY;
	}
	else {
		iOverlapHeight = iBottomA - _krRectB.m_iY;
	}

	if(iOverlapWidth < 0 || iOverlapHeight < 0) {
		return 0;
	}

	// Get and return the area.
	return iOverlapWidth * iOverlapHeight;
}
